package com.mibox.common.ui;

import android.annotation.SuppressLint;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.amap.api.location.AMapLocation;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.bumptech.glide.Glide;
import com.mibox.common.R;
import com.mibox.common.adapter.StockGridAdapter;
import com.mibox.common.adapter.StockUserAdapter;
import com.mibox.common.bean.BriefDataMsg;
import com.mibox.common.bean.CityId;
import com.mibox.common.bean.SinaStock;
import com.mibox.common.bean.SinaStocks;
import com.mibox.common.bean.TwoDayBrief;
import com.mibox.common.consts.MMKVKey;
import com.mibox.common.databinding.ActivityClockBinding;
import com.mibox.common.utils.HttpApi;
import com.mibox.common.utils.HttpCallback;
import com.mibox.common.utils.location.AMapCallback;
import com.mibox.common.utils.location.AMapHelper;
import com.mibox.common.utils.ticker.AppTicker;
import com.mibox.common.utils.ticker.TickCallback;
import com.tencent.mmkv.MMKV;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class ClockActivity extends AppCompatActivity
        implements AMapCallback, TickCallback {

    private ActivityClockBinding mB;
    private CityId mCityId = null;
    private BriefDataMsg.BriefData mBriefData = null;
    private int mDisplaySeconds = 0;
    private List<TwoDayBrief.EachDayData> mTwoDayBrief = null;
    private List<SinaStock> mTopStockList = new LinkedList<>();
    private List<SinaStock> mUserStockList = new LinkedList<>();
    private StockGridAdapter mStockBaseAdapter;
    private StockUserAdapter mStockUserAdapter;

    public static final String[] TOP_STOCKS = {"sh000001", "sz399001", "sz399006", "sh000688"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mB = ActivityClockBinding.inflate(getLayoutInflater());
        setContentView(mB.getRoot());
        initStockView();
        loadWifiInfo();
        loadLocationInfo();
        loadStockBrief();
        mB.weatherDiv.setOnClickListener(v -> ActivityUtils.startActivity(WeatherActivity.class));
        mB.mainClock.setTypeface(ResourcesCompat.getFont(this, R.font.font_lcd));
    }

    private void initStockView() {
        mB.stockBaseList.setLayoutManager(new GridLayoutManager(this, 4));
        mStockBaseAdapter = new StockGridAdapter();
        mB.stockBaseList.setAdapter(mStockBaseAdapter);
        mB.stockUserList.setLayoutManager(new LinearLayoutManager(this));
        mStockUserAdapter = new StockUserAdapter();
        mB.stockUserList.setAdapter(mStockUserAdapter);
    }

    @Override
    public void onSecondTick(long sec) {
        mDisplaySeconds += 1;
        if (mDisplaySeconds % 600 == 0) {
            loadRealTimeBrief();
            loadTwoDayBrief();
        }
        if (mDisplaySeconds % 3 == 0) {
            loadStockBrief();
        }
    }

    private void loadStockBrief() {
        List<String> stockCodes = new LinkedList<>();
        Collections.addAll(stockCodes, TOP_STOCKS);
        String codeStr = MMKV.defaultMMKV().getString(MMKVKey.KEY_STOCK_CODES, "");
        if (!StringUtils.isEmpty(codeStr)) {
            String[] userCodes = codeStr.split("\n");
            for (String code : userCodes) {
                code = code.trim();
                if (!StringUtils.isEmpty(code)) {
                    stockCodes.add(code);
                }
            }
        }
        HttpApi.getSinaStock(stockCodes, new HttpCallback<SinaStocks>() {
            @Override
            public void onSuccess(SinaStocks res) {
                List<SinaStock> stocks = res.data;
                handleStockData(stocks);
            }

            @Override
            public void onFail(String exp) {
            }
        });
    }

    private void handleStockData(List<SinaStock> stocks) {
        mTopStockList.clear();
        mUserStockList.clear();
        for (int i = 0; i < TOP_STOCKS.length; i++) {
            mTopStockList.add(stocks.remove(0));
        }
        mUserStockList.addAll(stocks);
        runOnUiThread(() -> {
            if (isDestroyed()) {
                return;
            }
            mStockBaseAdapter.setList(mTopStockList);
            mStockUserAdapter.setList(mUserStockList);
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        mDisplaySeconds = 0;
        AppTicker.INSTANCE.register(this);
    }

    @Override
    protected void onPause() {
        AppTicker.INSTANCE.unregister(this);
        super.onPause();
    }

    private void loadLocationInfo() {
        AMapHelper.INSTANCE.fetch(this, false);
    }

    private void loadWifiInfo() {
        String text = " 没有连接WiFi网络";
        if (NetworkUtils.isWifiConnected()) {
            text = "IP: " + NetworkUtils.getIpAddressByWifi();
        }
        mB.textNetInfo.setText(text);
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onLocationGet(AMapLocation location) {
        if (location.getLatitude() == 0) {
            ThreadUtils.runOnUiThreadDelayed(this::loadLocationInfo, 1000);
        } else {
            mB.textCityInfo.setText(location.getCity() + " " + location.getDistrict());
            HttpApi.getCityId(location, new HttpCallback<CityId>() {
                @Override
                public void onSuccess(CityId res) {
                    mCityId = res;
                    loadRealTimeBrief();
                    loadTwoDayBrief();
                }

                @Override
                public void onFail(String exp) {
                    ToastUtils.showShort(exp);
                }
            });
        }
    }

    private void loadTwoDayBrief() {
        if (mCityId != null) {
            HttpApi.getTwoDayBrief(mCityId.cityId, new HttpCallback<TwoDayBrief>() {
                @Override
                public void onSuccess(TwoDayBrief res) {
                    if (res.data != null && res.data.size() == 2) {
                        mTwoDayBrief = res.data;
                        runOnUiThread(() -> showTwoDayBrief());
                    }
                }

                @Override
                public void onFail(String exp) {
                    ToastUtils.showShort(exp);
                }
            });
        }
    }

    @SuppressLint("SetTextI18n")
    private void showTwoDayBrief() {
        if (isDestroyed()) {
            return;
        }
        TwoDayBrief.EachDayData day1 = mTwoDayBrief.get(0);
        Glide.with(this).load(day1.icon).into(mB.icToday);
        mB.txtTodayWeek.setText("今日 " + day1.week);
        mB.txtTodayTemp.setText(day1.minTemperature + "°~" + day1.maxTemperature + "°");
        TwoDayBrief.EachDayData day2 = mTwoDayBrief.get(1);
        Glide.with(this).load(day2.icon).into(mB.icDay2);
        mB.txtDay2Week.setText("明日 " + day2.week);
        mB.txtDay2Temp.setText(day2.minTemperature + "°~" + day2.maxTemperature + "°");
    }

    private void loadRealTimeBrief() {
        if (mCityId != null) {
            HttpApi.getRealTimeBrief(mCityId.cityId, new HttpCallback<BriefDataMsg>() {
                @Override
                public void onSuccess(BriefDataMsg res) {
                    mBriefData = res.data;
                    runOnUiThread(() -> showRealTimeBrief());
                }

                @Override
                public void onFail(String exp) {
                    ToastUtils.showShort(exp);
                }
            });
        }
    }

    private void showRealTimeBrief() {
        if (isDestroyed()) {
            return;
        }
        if (mBriefData != null) {
            mB.textTemper.setText(String.valueOf(mBriefData.temperature));
            mB.textWeather.setText(mBriefData.condition);
            mB.textWeatherEx.setText(getString(R.string.weather_ex_template,
                    mBriefData.wind, mBriefData.windPower, mBriefData.humidity,
                    mBriefData.aqi, mBriefData.airCondition));
        }
    }
}
